

/**
 * 判断是否为空
 * */
export function isNullOrEmpty(obj) {
  return (obj !== 0 || obj !== "0") && (obj === undefined || typeof obj === "undefined" || obj === null || obj === "null" || obj === "");
}
function isNotSomeDom(nodeName,domName){
  if(!nodeName || !domName) {
    return false;
  }
  if(nodeName.toLowerCase() != domName.toLowerCase()){
    return true;
  }
  return false;
}

/**
 * 判断是否为空对象
 * */
export function isEmptyObject(obj) {
  for (const key in obj) {
    return false;
  }
  return true;
}

/**
 * 获取有效点击元素，埋点采集只上报埋点元素
 * 全量采集找有ID或class的元素
 * */
export function getHelpfulElement(target, options, length = 0){
  //向上遍历到document，此次点击失效
  if (Object.prototype.toString.call(target) === Object.prototype.toString.call(document)){
    return null;
  }
  const parentNode = target && target.parentNode;
  const {className = '', id} = target;
  const {classTag, maxHelpfulCount} = options;
  //主动埋点
  if (!isNullOrEmpty(classTag)) {
    //未命中
    if(className.indexOf(classTag) < 0){
      if(isNullOrEmpty(parentNode)){
        return null;
      }else{
        if(length > maxHelpfulCount){
          return null;
        }else{
          return getHelpfulElement(parentNode, options, ++length)
        }
      }
    }else{
        return target
    }
  }else{
    // console.info('==全量采集===',target)
    //全量采集
    if(length > maxHelpfulCount){
      return null;
    }

    //如果当前元素没有className、ID
    if (isNullOrEmpty(className) && isNullOrEmpty(id) && isNotSomeDom(target.nodeName,'li')) {
      // debugger;
      if(target.nodeName == 'IMG' && target.nextElementSibling){//如果是img标签 看有没有相应的span标签
        return getHelpfulElement(target.nextElementSibling, options, ++length)
      } else if(isNullOrEmpty(parentNode)){
        return null;
      }else{
        return getHelpfulElement(parentNode, options, ++length)
      }
    } else if(target.nodeName == 'IMG' && target.nextElementSibling){//如果是img标签 看有没有相应的span标签
      return getHelpfulElement(target.nextElementSibling, options, ++length)
    }else{
      return target
    }
  }
}

/**
 * 获取元素所有属性
 * */
export function getAllAttr(elem) {
  const len = (elem.attributes ? elem.attributes.length : 0);
  const obj = {};
  if (len > 0) {
    for (let i = 0; i < len; i++) {
      const attr = elem.attributes[i];
      obj[attr.nodeName] = attr.nodeValue.replace(/"/igm, "'");
    }
  }
  return obj;
}

/**
 * 判断是否定义
 * @param v 变量
 * */
export function isDef(v) {
  return v !== undefined;
}

/**
 * 数据存储，可通过 useStorage 配置修改存储位置
 * @param name * 存储key
 * @param value * 存储内容
 * @param options 配置信息
 * */
export function setStorage(name, value) {
  if (!name) return null;
  // window.localStorage.setItem(name, serialize(value));
  window.sessionStorage.setItem(name, serialize(value));
}

/**
 * 存储读取
 * @param name * 存储key
 * @param options 配置信息
 * */
export function getStorage(name) {
  if (!name) return null;
  // let val = window.localStorage.getItem(name);
  let val = window.sessionStorage.getItem(name);
  return deserialize(val);
}

function serialize(val) {
  return JSON.stringify(val)
}

function deserialize(val) {
  if (typeof val !== 'string') {
    return undefined
  }
  try {
    return JSON.parse(val)
  } catch (e) {
    return val || undefined
  }
}

/**
 * 存储删除
 * @param name * 存储key
 * @param options 配置信息
 * */
export function delStorage(name) {
  // window.localStorage.removeItem(name);
  window.sessionStorage.removeItem(name);
}

/**
 * 生成UUID
 * @param len * UUID长度,默认16
 * @param radix 进制，默认16
 * */
export function getUuid(prefix,len = 16, radix = 16) {//uuid长度以及进制
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  const uuid = [];
  for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
  return prefix + uuid.join('');
}

/**
 * 获取时间戳
 * @return timeStamp: Number
 * */
export function getTime() {
  const date = new Date();
  let month = _addZero(date.getMonth() + 1);
  let day = _addZero(date.getDate());
  let h = _addZero(date.getHours());
  let m = _addZero(date.getMinutes());
  let s = _addZero(date.getSeconds());
  let ms = _addZero(date.getMilliseconds(),'000');
  return {
    //生成yyyyMMddHHmmssSSS格式
    timeStr: `${date.getFullYear()}${month}${day}${h}${m}${s}${ms}`,
    timeStamp: date.getTime()
  }
}
//时分秒 前面补0，如8月，从‘8’变成‘08’ 
function _addZero(p,prefixZero = '00'){
  let retValue = p+'';
  if(p>=0){
    retValue = (prefixZero + p).substring(retValue.length);
  }
  return retValue;
}
/**
 * 配置项合并
 * */
export function mergeOption(userOpt, baseOpt) {
  const newOpt = {};
  const keys = Object.keys(baseOpt);

  for (let i = 0; i < keys.length; i++) {
    newOpt[keys[i]] = isDef(userOpt[keys[i]]) ? userOpt[keys[i]] : baseOpt[keys[i]];
  }

  return newOpt;
}

/**
 * 配置项检查
 * */
export function checkOptions(options) {
  let flag = true;
  if (isEmptyObject(options)) {
    warn(`--------配置项异常：不能为空------`);
    return false;
  }
  const notEmpty = ['storeInput', 'storePage', 'storeClick', 'storeReqErr', 'storeTiming', 'storeCodeErr', 'storeCustom',
    'storeSourceErr', 'storePrmseErr', 'storeCompErr', 'storeVueErr',
    'userSha', 'useImgSend', 'useStorage', 'openInput', 'openClick', 
    'openPage', 'openComponent', 'openXhrTimeOut']
  notEmpty.map(key => {
    if (isNullOrEmpty(options[key])) {
      warn(`--------配置项【${key}】不能为空------`)
      flag = false;
    }
  });
  // 上报方式检查
  if (options['useImgSend']) {
    if (isNullOrEmpty(options['imageUrl'])) {
      warn(`--------使用图片上报数据，需要配置 【imageUrl】------`)
      return false;
    }
  } else {
    if (isNullOrEmpty(options['postUrl'])) {
      warn(`--------使用接口上报数据，需要配置 【postUrl】------`)
      return false;
    }
  }

  //输入框采集配置
  if (options['openInput']) {
    if (isNullOrEmpty(options['selector'])) {
      warn(`--------请指定输入框选择器：selector------`)
      return false;
    }
  }
  //存储配置
  if (options['useStorage']) {
    if (typeof window.localStorage === 'undefined') {
      warn(`--------当前容器不支持Storage存储：useStorage------`)
      return false;
    }
  }
  return flag
}

/**
 *  警告
 * */
export function warn(message) {
  if (process.env.NODE_ENV !== 'production') {
    typeof console !== 'undefined' && console.warn(`[CallChainLog] ${message}`)
  }
}

/**
 *  内嵌AJAX
 * */
export function nlAjax(options = {}) {
  let xhr, params;
  options.type = (options.type || "GET").toUpperCase();
  options.dataType = (options.dataType || "json");
  options.async = (options.async || true);
  if (options.data) {
    params = options.data;
  }
  if (window.XMLHttpRequest) {
    // 非IE6
    xhr = new XMLHttpRequest();
    if (xhr.overrideMimeType) {
      xhr.overrideMimeType('text/xml');
    }
  } else {
    //IE6及其以下版本浏览器
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }

  if (options.type === "GET") {
    xhr.open("GET", options.url + "?" + params, options.async);
    xhr.send(null);
  } else if (options.type === "POST") {
    xhr.open("POST", options.url, options.async);
    xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
    if (params) {
      xhr.send(params);
    } else {
      xhr.send();
    }
  }
}

/**
 *  格式化Vue异常
 *
 * */
export function formatVueErrStack(error) {
  const msg = error.toString();
  let stack = error.stack ? error.stack
    .replace(/\n/gi, "") // 去掉换行
    .replace(/\bat\b/gi, "@")
    .replace(/\?[^:]+/gi, "")
    .replace(/^\s*|\s*$/g, "")
    .split("@") // 以@分割信息
    .slice(0, 5) //只取5条
    .join("&&") : '';
  if (stack.indexOf(msg) < 0) stack = msg + "@" + stack;
  return stack;
}
const _tid = ()=>{
  var myDate = new Date();
  var uuid = myDate.getDay()+myDate.getHours()+myDate.getMinutes()+myDate.getMinutes()+myDate.getMilliseconds()+Math.round(Math.random()*10000);
  return uuid;
}
const _rid = ()=>{
  return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
export function getUuidRandom(prefix){
  return (prefix+_tid() + _rid()+ _rid() + _rid() );
}




/**
 * 用于处理两个大数的相减
 * @param {string} num1 被减数
 * @param {string} num2 减数
 * @returns {string} 差
 */
export function subtract(num1, num2) {
    // 确保num1的长度不小于num2的长度
    if (num1.length < num2.length) {
        [num1, num2] = [num2, num1];
    }
    let len1 = num1.length - 1;
    let len2 = num2.length - 1;
    let carry = 0; // 进位
    let ans = ''; // 差
    while (len1 >= 0 || len2 >= 0) {
        let n1 = len1 >= 0 ? num1[len1] - '0' : 0;
        let n2 = len2 >= 0 ? num2[len2] - '0' : 0;
        let sub = n1 - n2 - carry; // 当前位的差
        if (sub < 0) {
            sub += 10;
            carry = 1;
        } else {
            carry = 0;
        }
        ans += sub.toString();
        len1--;
        len2--;
    }
    return ans.split('').reverse().join('').replace(/^0+/, '') || '0';
}



export function bigNumSub(a, b) {
  //判断当前浏览器支持bigInt
  if (typeof BigInt == "undefined") {
    return ex(a,b);
  }
  let c = BigInt(a) - BigInt(b);
  return Number(c)
}


